import java.io.*;
import java.text.ParseException;
import java.util.*;


/**
 * Class MarkerInput is an input class for assignment submission and view assignments status.
 */
class MarkerInput {
	private String markerID;
	private String password;
	private String option; 
	private String subjectID;
	private String assignmentID;
	private String studentID;
        private String markFile;
        
	public MarkerInput(String[] data) {
		if (data.length > 1) {
			markerID=data[0];
			password=data[1];
			option=data[2];
			if (option.equals("1")) {
				subjectID=data[3];
				assignmentID=data[4];
				studentID=data[5];
			}
			else
                            if (option.equals("2"))
                            {
				if (data.length > 4) {subjectID=data[3];}
				if (data.length > 4) assignmentID=data[4];
                            }
                            else
                                {
                                    if (data.length > 4) subjectID=data[3];
                                    if (data.length > 4) assignmentID=data[4];

                                    if (data.length > 6) studentID = data[5];
                                    if (data.length > 6) markFile = data[6];
                                }
		}
	}
	
	public String getMarkerID() {
		return markerID;
	}
	public String getPassword() {
		return password;
	}
	public String getOption() {
		return option;
	}
	public String getSubjectID() {
		return subjectID;
	}
	public String getAssignmentID() {
		return assignmentID;
	}
        public String getStudentID() {
		return studentID;
	}
        public String getMarkFile() {
		return markFile;
	}
}

/**
 * Class Assignment for subject's assignment data
 */
class Assignment {
//	A01,Agile Assignment 1,HIT8098,2010-03-11 17:30:00
	private String assignmentID;
	private String title;
	private String subjectID;
	private String dueDate;

	public Assignment(String[] data) {
		assignmentID=data[0];
		title=data[1];
		subjectID=data[2];
		dueDate=data[3];
	}

	public String getAssignmentID() {
		return assignmentID;
	}
	public String getSubjectID() {
		return subjectID;
	}
	public String getDueDate() {
		return dueDate;
	}
}


/**
 * Class Enrollment for student's enrollment data to certain subject 
 */
class Registration {
// 333,HIT8098
	private String markerID;
	private String subjectID;

	public Registration(String[] data) {
		markerID=data[0];
		subjectID=data[1];
	}
	public String getMarkerID() {
		return markerID;
	}
	public String getSubjectID() {
		return subjectID;
	}
}


/**
 * Class Submission for student's assignment submission data 
 */
class Submission {
	private String submissionID;
	private String studentID;
	private String subjectID;
	private String assignmentID;
	private String dateTimeSubmission;
	private String submissionFile;
	private String latePenalty;
	private String markStatus;
	private String mark;
        
	public Submission(String[] data) {
		if (data.length > 1) {
                    submissionID=data[0];
		    studentID=data[1];
		    subjectID=data[2];
		    assignmentID=data[3];
		    dateTimeSubmission=data[4];
		    submissionFile=data[5];
		    latePenalty=data[6];
		    markStatus=data[7];
                    if (data.length > 8)
                        mark = data[8];
		}
	}
	
	public String getSubmissionID() { 
		return submissionID; 
	}
	public String getStudentID() { 
		return studentID; 
	}
	public String getSubjectID() {
		return subjectID; 
	}
	public String getAssignmentID() {
		return assignmentID; 
	}
	public String getDateTimeSubmission() {
		return dateTimeSubmission;
	}
	public String getSubmissionFile() {
		return submissionFile;
	}
	public String getLatePenalty() {
		return latePenalty;
	}
	public String getMarkStatus() {
		return markStatus;
	}
        public String getMark() {
		return mark;
	}
}

/**
 * Class submissionMain is the main program of student's submission process 
 * @throws IOException, ParseEcxeption
 */
public class SubmissionMain {
	ArrayList<String> data;
	ArrayList<String> result;
	ArrayList<MarkerInput> mkrInput = new ArrayList<MarkerInput>();
	ArrayList<Registration> registrationData = new ArrayList<Registration>();
	ArrayList<Assignment> assignmentData = new ArrayList<Assignment>();
	ArrayList<Submission> submissionData = new ArrayList<Submission>();
    static String INPUT_FILE;
    static final String LOGIN_FILE = "marker.txt";
    static final String REGISTRATION_FILE = "registration.txt";
    static final String ASSIGNMENT_FILE = "assignment.txt";
    static final String SUBMISSION_FILE = "submission.txt";
    static final String MARKER_FILE = "marker.txt";
    int noReceipt=0;

	public SubmissionMain(String inputFile) throws IOException, ParseException {
        INPUT_FILE = inputFile;
		initObject();
		process(mkrInput);
	}	

/**
 * Get the data from text file and object initialization  
 */
    public void initObject() throws IOException {
	data = new ArrayList<String>();
        data.clear();
	readFile.readFrom(INPUT_FILE, data);
        for (int i=0; i<data.size(); i++)
            if (data.get(i).split(",").length > 1)
            {
        	mkrInput.add(new MarkerInput(data.get(i).split(",")));
            }

	data = new ArrayList<String>();
	readFile.readFrom(REGISTRATION_FILE, data);
        for (int i=0; i<data.size(); i++) {
        	registrationData.add(new Registration(data.get(i).split(",")));
        }

	data = new ArrayList<String>();
	readFile.readFrom(ASSIGNMENT_FILE, data);
        for (int i=0; i<data.size(); i++) {
        	assignmentData.add(new Assignment(data.get(i).split(",")));
        }

        data = new ArrayList<String>();
	readFile.readFrom(SUBMISSION_FILE, data);
        noReceipt=data.size();
    }
	
/**
 * marker downloads an assignment
 */
    public void downloadAssignment( MarkerInput mkr) throws IOException
    {
        // get all assignments of a marker
        getAssignmentStatus( mkr );
        submissionData.clear();
        
        for (int i=0; i<result.size(); i++) {
                Submission sub1 = new Submission( result.get(i).split(","));
        	submissionData.add( sub1 );
        }

        for ( Submission sub : submissionData)
            if ( ( mkr.getStudentID().equals( sub.getStudentID()) ) && 
                 ( mkr.getAssignmentID().equals( sub.getAssignmentID())) )
               {
                    ArrayList<String> assignmentFile = new ArrayList<String>();
                    readFile.readFrom( sub.getSubmissionFile(), assignmentFile);
                    // check status
                    String fileName = "";
                    if ( sub.getMarkStatus().equals( "N") )
                        fileName = mkr.getMarkerID() + "_" + sub.getStudentID() + "_" + sub.getSubjectID() +
                                   "_" + sub.getAssignmentID() + ".txt";

                    if (!fileName.equals(""))
                            writeFile.writeTo( fileName, assignmentFile, false);
                    break;
               }        
    }

/**
 * Process for marker's submission and view status assignment
 */
    public void process(ArrayList<MarkerInput> mkrInput) throws IOException, ParseException
    {
        for (int i=0; i<mkrInput.size(); i++) {
            if (checkLogin(mkrInput.get(i))) {
                if (((mkrInput.get(i)).getOption().equals("1"))) {
                    result = new ArrayList<String>();
                    downloadAssignment(mkrInput.get(i));
                }
                else
                if (((mkrInput.get(i)).getOption().equals("2")))
                        viewStatus(mkrInput.get(i));
                  else if (((mkrInput.get(i)).getOption().equals("3")))
                        uploadMarkedAssignment(mkrInput.get(i));
                    else {
                        result = new ArrayList<String>();
                        result.add("Option Data:"+(mkrInput.get(i)).getOption()+" Is Not Valid!");
                        writeFile.writeTo(SUBMISSION_FILE, result, true);
                    }
            }
            else {
                    result = new ArrayList<String>();
                    result.add("Login Data Is Not Valid!");
                    writeFile.writeTo(SUBMISSION_FILE, result, true);
            }
        }
    }
    
/**
 * Match the login input with the login data in the text file  
 */
    public boolean checkLogin(MarkerInput std) throws IOException {
			data = new ArrayList<String>();
	        readFile.readFrom(LOGIN_FILE, data);

	        for (int i = 0; i< data.size(); i++) {
	            String[] identity = data.get(i).split(",");
	            if ( std.getMarkerID().toUpperCase().equals(identity[0].toUpperCase()) &&
	            	 std.getPassword().equals(identity[1]) )
	            	return true;
	        }
	        return false;
	    }		

/**
 * Find registration data for a particular marker
 */
    private boolean findRegistration(MarkerInput mkr) {
		for (Registration en : registrationData) {
			if (en.getMarkerID().equals(mkr.getMarkerID())
				&& en.getSubjectID().toUpperCase().equals(mkr.getSubjectID().toUpperCase())) {
			     return true;
			}
		}
		return false;
	}

/**
 * Download all assignments that a marker is responsible for, put them to results
 *
 */
    public void getAssignmentStatus(MarkerInput mkr) throws IOException
    {
        //StudentID, subject, AssignmentID, submissionStatus, submissionFile, dateTimeSubmission, deadLine, latePenaltyPercentage, mark status, mark
	result = new ArrayList<String>();
        for (Registration re : registrationData)
            if (re.getMarkerID().equals(mkr.getMarkerID()) )
                for (Submission sub : submissionData) {
                    if (re.getSubjectID().equals(sub.getSubjectID())) {
                        String resultStr = sub.getSubmissionID() + "," + sub.getStudentID() + "," + sub.getSubjectID() + "," + sub.getAssignmentID() + "," ;

                        resultStr += sub.getDateTimeSubmission()+ "," + sub.getSubmissionFile() + "," + sub.getLatePenalty()
                                    + "," + sub.getMarkStatus();

                        if (sub.getMarkStatus().toUpperCase().equals("Y"))
                            resultStr += "," + sub.getMark();
                        result.add(resultStr);
                    }
                }

        if (result.size()==0)
            result.add("Assignments Data for this Marker ID:"+mkr.getMarkerID()+" is Not Found!");

    }

/**
 *
 * Download data from submission file
 */
    public void downloadData() throws IOException
    {
        data = new ArrayList<String>();
        readFile.readFrom(SUBMISSION_FILE, data);

        submissionData.clear();
        for (int i=0; i<data.size(); i++)
          if (data.get(i).split(",").length > 1)
          {
             submissionData.add(new Submission(data.get(i).split(",")));
          }
    }
    
/**
 * View the status of all student's submitted work  
 */
    public void viewStatus(MarkerInput mkr) throws IOException {
	
        downloadData();
        // get all assignments of a marker
        getAssignmentStatus( mkr );

        writeFile.writeTo(mkr.getMarkerID()+".txt", result, false);        
    }        

    public void uploadMarkedAssignment(MarkerInput mkr) throws IOException {
        getAssignmentStatus( mkr );

        if ( result.size() > 0 )
        {

            downloadData();
            for ( Submission sub:submissionData)
                if (sub.getStudentID().equals( mkr.getStudentID() )  &&
                    sub.getSubjectID().equals( mkr.getSubjectID() )  &&
                    sub.getAssignmentID().equals( mkr.getAssignmentID() )  
                    )
                    {
                        String markFile = "";
                        markFile = mkr.getAssignmentID() + mkr.getSubjectID() + "_" + mkr.getStudentID() + ".txt";

                        data.clear();
                        readFile.readFrom(mkr.getMarkFile(), data);
                        writeFile.writeTo(markFile, data, false);
                    }
        }        
    }
    
    public static void main(String[] args) throws IOException, ParseException {
    	if (args.length > 0) {
        	new SubmissionMain(args[0]);
    	}
    }
  
}
